/********************************************************************************
 * Project Name		[JavaEE_Web]
 * File Name     	[Servlet06.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package _notes.servlet;

/**
 * 监听器
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public final class Servlet06 {

	public void listenerConcept() {
		/**
		 * 监听器: 专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象, 当被监视的对象发生情况时, 立即采取相应的行动<br/>
		 * Servlet监听器: Servlet规范中定义的一种特殊类, 它用于监听Web应用程序中的ServletContext,
		 * HttpSession和 ServletRequest等域对象的创建与销毁事件, 以及监听这些域对象中的属性发生修改的事件<br/>
		 */
	}

	public void listenerTypes() {
		/**
		 * Servlet监听器分类<br/>
		 * 监听域对象自身的创建和销毁的事件监听器<br/>
		 * 监听域对象中的属性的增加和删除的事件监听器<br/>
		 * 监听绑定到HttpSession域中的某个对象的状态的事件监听器<br/>
		 */
	}

	public void createOwnListeners() {
		/**
		 * 编写Servlet监听器<br/>
		 * 1. 编写类, 这些类实现了Servlet指定的监听器接口<br/>
		 * 2. 在web.xml中注册监听器<br/>
		 * 
		 * 注意<br/>
		 * 1. Servlet事件监听器的注册和调用过程都是由Web容器自动完成的<br/>
		 * 2. 当发生被监听的对象被创建, 修改或销毁事件时, Web容器将调用与之相关的Servlet事件监听器对象的相关方法<br/>
		 * 3. 开发人员在在这些方法中编写的事件处理代码即被执行<br/>
		 * 4. 在编写事件监听器类时应考虑多线程安全的问题<br/>
		 * 5. 一个 web.xml文件中可以注册多个Servlet事件监听器,
		 * Web服务器按照它们在web.xml文件中的注册顺序来加载和注册这些Servlet事件监听器<br/>
		 */
	}

	public void listenerXmlConfiguration() {
		/**
		 * Listener的web.xml配置<br/>
		 * <code>
		 * <listener>
		 *     <listener-class>listener.MyServletContextListener</listener-class>
		 * </listener>
		 * </code>
		 */
	}

	public void listenerAnnotationConfiguration() {
		/**
		 * Listener的注解配置<br/>
		 * <code>
		 * <pre>@WebListener(value = "MyServletContextListener")<pre>
		 * </code>
		 */
	}

	public void scopesListeners() {
		/**
		 * 域对象创建和销毁的监听器监听器<br/>
		 * 
		 * 1. ServletContextListener用于监听ServletContext对象的创建和销毁事件<br/>
		 * 
		 * 方法<br/>
		 * contextInitialized(ServletContextEvent e);
		 * 当ServletContext对象被创建时该方法被调用 <br/>
		 * contextDestroyed(ServletContextEvent e); 当ServletContext对象被销毁时该方法被调用
		 * <br/>
		 * e.getServletContext(); 通过ServletContextEvent来得到ServletContext对象<br/>
		 * 
		 * 最常用的Listener, 可以在当前Web应用被加载时对当前Web应用的相关资源进行初始化操作, 例如: 创建数据库连接池,
		 * 创建Spring的IOC容器, 读取当前Web应用的初始化参数 ...<br/>
		 *
		 * 2. HttpSessionListener用于监听HttpSession对象的创建和销毁<br/>
		 * 
		 * 方法<br/>
		 * sessionCreated(HttpSessionEvent e); 创建一个Session对象时该方法被调用<br/>
		 * sessionDestroyed(HttpSessionEvent e); 销毁一个Session对象时该方法被调用<br/>
		 *
		 * 3. ServletRequestListener用于监听ServletRequest对象的创建和销毁<br/>
		 * 
		 * 方法<br/>
		 * requestInitialized(ServletRequestEvent e);
		 * 创建一个ServletRequest对象时该方法被调用 <br/>
		 * requestDestroyed(ServletRequestEvent e); 销毁一个ServletRequest对象时该方法被调用
		 * <br/>
		 */

		/**
		 * 利用上述三个Listener, 可以追踪request, session, application的生命周期<br/>
		 * 
		 * 1. request: 是一个请求, 当发送一个请求时被创建, 当一个响应返回时被销毁<br/>
		 * 请求转发的过程是一个request对象, 重定向是两个request<br/>
		 * 
		 * 2. session: <br/>
		 * 创建: 当第一次访问Web应用的一个JSP或Servlet时, 且该JSP或Servlet中还需要创建Session时<br/>
		 * 销毁: 当Session过期, 或调用Session的invalidate方法, 或当前Web应用被卸载时[Session持久化问题]
		 * <br/>
		 * Session持久化: 当服务器关闭时,
		 * Tomcat会在TomcatHome/work/Catalina/localhost/yourApp下创建一个持久化的Session文件[
		 * SESSION.ser]<br/>
		 * 关闭浏览器, 并不意味着Session被销毁, 还可以通过SessionID找到服务器中的Session对象<br/>
		 * <code>
		 * http://localhost:8080/JavaEE_Web/jsp/helloWorld.jsp;jsessionid=34B1060052C49BE1D9EDAB5A001F3169
		 * </code>
		 *
		 * 3. application: 贯穿于当前的Web应用的生命周期, 当前Web应用被加载时创建application对象, 当前Web
		 * 应用被卸载时销毁application对象<br/>
		 */
	}

	public void attributesListeners() {
		/**
		 * 域对象中属性的变更的事件监听器<br/>
		 * 
		 * 1. ServletContextAttributeListener<br/>
		 * 
		 * 方法<br/>
		 * attributeAdded(ServletContextAttributeEvent e);
		 * 向ServletContext中添加属性时被调用 <br/>
		 * attributeRemoved(ServletContextAttributeEvent e);
		 * 从ServletContext中移除属性时被调用<br/>
		 * attributeReplaced(ServletContextAttributeEvent e);
		 * ServletContext中属性发生变化时被调用<br/>
		 * 
		 * 2. HttpSessionAttributeListener<br/>
		 * 
		 * 方法<br/>
		 * attributeAdded(HttpSessionBindingEvent e); 向Session中添加属性时被调用<br/>
		 * attributeRemoved(HttpSessionBindingEvent e); 从Session中移除属性时被调用<br/>
		 * attributeReplaced(HttpSessionBindingEvent e); Session中的属性发生变化时被调用
		 * <br/>
		 * 
		 * 3. ServletRequestAttributeListener<br/>
		 * 
		 * 方法<br/>
		 * attributeAdded(ServletRequestAttributeEvent e); 向Request中添加属性时被调用
		 * <br/>
		 * attributeRemoved(ServletRequestAttributeEvent e); 从Request中移除属性时被调用
		 * <br/>
		 * attributeReplaced(ServletRequestAttributeEvent e);
		 * Request中的属性发生变化时被调用 <br/>
		 */
	}

	public void sessionBindListener() {
		/**
		 * 1. HttpSessionBindingListener<br/>
		 * 实现了此接口的JavaBean对象可以感知自己被绑定到Session中和从Session中删除的事件<br/>
		 * 
		 * 方法<br/>
		 * valueBound(HttpSessionBindingEvent event); 当前对象被绑定到Session时调用该方法<br/>
		 * valueUnbound(HttpSessionBindingEvent event); 当前对象从Session中解除绑定调用该方法
		 * <br/>
		 * 
		 * 2. HttpSessionActivationListener<br/>
		 * 实现了此接口的JavaBean对象可以感知自己被活化和钝化的事件<br/>
		 * 
		 * 方法<br/>
		 * sessionWillPassivate(HttpSessionBindingEvent e);
		 * 在绑定到HttpSession中的JavaBean对象将要随HttpSession被钝化之前调用<br/>
		 * sessionDidActive(HttpSessionBindingEvent e);
		 * 在绑定到HttpSession中的JavaBean对象将要随HttpSession被活化之后调用<br/>
		 * 
		 * <>活化: 从磁盘中读取Session对象, JavaBean对象和Session一起被反序列化到内存中<br/>
		 * <>钝化: 向磁盘中写入Session对象, JavaBean对象存在Session中, 当服务器把session序列化到硬盘上时,
		 * 如果Session中的JavaBean对象实现了Serializable接口,
		 * 那么服务器会把session中的JavaBean对象一起序列化到硬盘上,
		 * JavaBean对象和Session一起被序列化到硬盘中的这个操作称之为钝化,
		 * 如果Session中的JavaBean对象没有实现Serializable接口,
		 * 那么服务器会先把Session中没有实现Serializable接口的JavaBean对象移除, 然后再把Session序列化到硬盘中
		 * <br/>
		 * 
		 * 当绑定到HttpSession对象中的JavaBean对象将要随HttpSession对象被钝化之前,
		 * Web服务器调用该JavaBean对象的sessionWillPassivate()方法,
		 * 这样JavaBean对象就可以知道自己将要和HttpSession对象一起被序列化[钝化]到硬盘中<br/>
		 * 
		 * 当绑定到HttpSession对象中的JavaBean对象将要随HttpSession对象被活化之后,
		 * Web服务器调用该JavaBean对象的sessionDidActive()方法, 这样JavaBean对象就可以知道自己将要和
		 * HttpSession对象一起被反序列化[活化]回到内存中<br/>
		 * 
		 * Session对象存储在TomcatHome/work/Catalina/localhost/yourApp下[SESSION.SER]
		 * <br/>
		 * 
		 * 实现以上两个接口的监听器不需要在web.xml中注册<br/>
		 */
	}
}
